﻿using System;
using System.Collections;
using System.Linq;
using Autodesk.AutoCAD.Interop;
using Autodesk.AutoCAD.Runtime;

namespace AutoCADDotNetLibrary
{
    /// <summary>
    /// 菜单特性
    /// </summary>
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
    public class AcadPopupMenuItemAttribute : Attribute
    {
        /// <summary>
        /// Com菜单特性
        /// </summary>
        /// <param name="label">名称</param>
        /// <param name="index">顺序</param>
        public AcadPopupMenuItemAttribute(string label, int index)
        {
            Label = label;
            Index = index;
        }

        /// <summary>
        /// 名称
        /// </summary>
        public string Label { get; private set; }

        /// <summary>
        /// 顺序
        /// </summary>
        public int Index { get; private set; }

        /// <summary>
        /// 选中
        /// </summary>
        public bool Check { get; set; } = false;

        /// <summary>
        /// 使用
        /// </summary>
        public bool Enable { get; set; } = true;

        /// <summary>
        /// 帮助信息
        /// </summary>
        public string HelpString { get; set; }

        /// <summary>
        /// 是否后面添加分隔符
        /// </summary>
        public bool IsAddSeparatorAfter { get; set; } = false;

        /// <summary>
        /// 特性转换
        /// </summary>
        /// <param name="menu"></param>
        /// <param name="command"></param>
        /// <returns></returns>
        internal AcadPopupMenuItem GetAcadPopupMenuItem(AcadPopupMenu menu, string command)
        {
            AcadPopupMenuItem item = menu.AddMenuItem(menu.Count, Label, ((char)27) + command.Trim() + "\n");
            if (!string.IsNullOrEmpty(HelpString))
                item.HelpString = HelpString;

            item.Check = Check;
            item.Enable = Enable;

            if (IsAddSeparatorAfter)
                menu.AddSeparator(menu.Count);

            return item;
        }
    }

    /// <summary>
    /// com菜单
    /// </summary>
    public static class AcadPopupMenuItemAtt
    {
        /// <summary>
        /// 添加类型中的菜单项
        /// </summary>
        /// <param name="menu">子菜单</param>
        /// <param name="t">具有实现了<see cref="AcadPopupMenuItemAttribute"/>和<see cref="CommandMethodAttribute"/>的方法的类型</param>
        /// <returns>子菜单</returns>
        public static AcadPopupMenuItem[] AddAcadPopupMenuItem(this AcadPopupMenu menu, Type t)
        {
            AcadPopupMenuItem[] list = t.GetMethods().Select(x => new
            {
                Menu = x.GetCustomAttributes(typeof(AcadPopupMenuItemAttribute), false).OfType<AcadPopupMenuItemAttribute>(),
                Command = x.GetCustomAttributes(typeof(CommandMethodAttribute), false).OfType<CommandMethodAttribute>(),
            }).Where(x => x.Menu.Count() != 0 && x.Command.Count() != 0)
               .Select(x => new
               {
                   Command = x.Command.First().GlobalName,
                   Menubar = x.Menu.First(),
               }).OrderBy(x => x.Menubar.Index).Select(x =>
               {
                   AcadPopupMenuItem menuItem = x.Menubar.GetAcadPopupMenuItem(menu, x.Command);

                   return menuItem;
               }).ToArray();

            return list;
        }


        /// <summary>
        /// 项根据路径找com菜单项
        /// </summary>
        /// <param name="AcadApplication">comApp</param>
        /// <param name="menuName">菜单路径</param>
        /// <returns>类型：AcadPopupMenuItem</returns>
        public static AcadPopupMenuItem GetAcadPopupMenuItem(this AcadApplication AcadApplication, params string[] menuName)
        {
            if (menuName.Length < 3)
                return null;

            AcadPopupMenus t1 = AcadApplication.MenuGroups.Cast<AcadMenuGroup>().FirstOrDefault(x => x.Name == menuName[0]).Menus;
            AcadPopupMenu t2 = t1.Cast<AcadPopupMenu>().FirstOrDefault(x => x.Name == menuName[1]);
            AcadPopupMenuItem r = t2.Cast<AcadPopupMenuItem>().FirstOrDefault(x => x.Label == menuName[2]);


            for (int i = 3; i < menuName.Length; i++)
            {
                r = ((IEnumerable)r.SubMenu).Cast<AcadPopupMenuItem>().FirstOrDefault(x => x.Label == menuName[i]);
                if (menuName.Length == i + 1)
                    return r;
            }

            return r;
        }
    }
}